#include <stdlib.h> 
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <assert.h>

char game[3][3] = {
        {'-','-','-'},
        {'-','-','-'},
        {'-','-','-'}
};

int won(char c) {
  if (game[0][0] == c && game[1][0] == c && game[2][0] == c)
                return 1;
        if (game[0][1] == c && game[1][1] == c && game[2][1] == c)
                return 1;
        if (game[0][2] == c && game[1][2] == c && game[2][2] == c)
                return 1;
        if (game[0][0] == c && game[0][1] == c && game[0][2] == c)
                return 1;
        if (game[1][0] == c && game[1][1] == c && game[1][2] == c)
                return 1;
        if (game[2][0] == c && game[2][1] == c && game[2][2] == c)
                return 1;
        if (game[0][0] == c && game[1][1] == c && game[2][2] == c)
                return 1;
        if (game[0][2] == c && game[1][1] == c && game[2][0] == c)
                return 1;
        return 0;

}

void set_move(char* move) {
        game[move[0] - '1'][move[2] - '1'] = move[4];
}

int empty(int i, int j) {
        return (game[i][j] == '-');
}


void read_from_FIFO(char* fifo, char* target) {
        int i = 0, fd;
        int c;
        fd = open(fifo, O_RDONLY);
        while ((c = read_char(fd)) != '\n' && c != EOF)
                target[i++] = (char) c;
        close(fd);
}

void write_to_FIFO(char* fifo, char* source) {
        int fd = open(fifo, O_WRONLY);
        write(fd, source, strlen(source));
        write(fd, "\n", 1);
        close(fd);
}

int check(char* move) {
        if (strlen(move) > 5) {
                return 0;
        }
        if (move[0] < '1' || move[0] > '3') {
                return 0;
        }
        if (move[1] != '_') {
                return 0;
        }
        if (move[2] < '1' || move[2] > '3') {
                return 0;
        }
        if (move[3] != '_') {
                return 0;
        }
        if (move[4] != 'X' && move[4] != 'O') {
                return 0;
        }
        if (!empty(move[0] - '1', move[2] - '1')) {
                return 0;
        }
        return 1;
}

void draw() {
        int i, j;
  for (i = 0; i < 3; i++) {
                for (j = 0; j < 3; j++)
                        printf("%c", game[i][j]);
                printf("\n");
        }
}

void write_to_fifo(char* fifo, char* source) {
        int fd = open(fifo, O_WRONLY);
        source[strlen(source)] = '\n';
        write(fd, source, strlen(source));
        close(fd);
}

void read_from_fifo(char* fifo, char* target) {
        int i = 0, fd;
        int c;
        printf("curR: %s ", fifo);
        fflush(stdout);
        fd = open(fifo, O_RDONLY);
        while ((c = read_char(fd)) != '\n' && c != EOF) {
                target[i++] = (char) c;
                printf("%c", c);
                fflush(stdout);
        }
        close(fd);
}

int read_char(int fd) {
        char buf[1];
        int t;
        t = read(fd, buf, 1);
        if (t == -1 || t == 0)
                return EOF;
        return buf[0];
}

int main(int argc, char** argv) {
				int fd, fd1, i;
				char move[5];

				if (mkfifo(argv[1], 0777) == -1 && errno != EEXIST) {
								printf ("error\n");
								exit (EXIT_FAILURE);
				}

				if (mkfifo(argv[2], 0777) == -1 && errno != EEXIST) {
								printf ("error\n");
								exit (EXIT_FAILURE);
				}
		
				
				fd = open(argv[1], 0777);
				fd1 = open(argv[2], 0777);

				if (strcmp(argv[3], "1") == 0) {
								scanf ("%s", move);
								
								if (check(move)) {
												write (fd1, move, 5);
												set_move (move);
												draw();
												if (won(move[4])) {
																printf ("you win\n");
																return 0;
												}
								}	else {							
												write (fd1, "error", 5);
												exit (EXIT_FAILURE);
								}
				}

				

				for (i = 0; i < 8; i++) {
								read (fd, move, 5);
								if (check(move)) {
												draw ();
												set_move (move);
												if (won(move[4])){
																printf ("you lose");
																return 0;
												}
								} else {
												exit(EXIT_FAILURE);				
								}
								
								scanf ("%s", move);
								
								if (check(move)) {
												write (fd1, move, 5);
												set_move (move);
												draw();
												if (won(move[4])) {
																printf ("you win\n");
																return 0;
												}
								}	else {							
												write (fd1, "error", 5);
												exit (EXIT_FAILURE);
								}
				}
				
				if (strcmp(argv[3], "1")) {
								
								read (fd, move, 5);
								if (check(move)) {
												draw ();
												set_move (move);
												if (won(move[4])){
															printf ("you lose\n");
																return 0;
												}
								} else {
												exit(EXIT_FAILURE);				
								}
				}
				close (fd);
				close (fd1);
				printf ("draw\n");
				return 0;
}
